package com.ivanceras.shared.db;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.ivanceras.shared.db.IModelDef;

public class ModelDef implements IModelDef{
	
	private String namespace;
	private String modelName;
	private String[] attributes;
	private String generatedAttribute;
	private String[] primaryAttributes;
	private String[] uniqueAttributes;
	private String[] dataTypes;
	private Object[] values;
	private String[] hasOne;
	private String[] hasOneForeignColumn;
	private String[] hasMany;
	private String[] hasManyForeignColumn;
	private String[] hasManyMany;
	private String[] hasManyManyInvolvedModel; /** intermediatiary involved models to connect between many to many relationship of records **/
	private String[] hasManyManyInvolvedModelForeignColumn;
	private boolean caseSensitive;
	
	
	public ModelDef(String namespace, String modelName, String[] attributes, String generatedAttribute,
			String[] dataTypes, String[] primaryAttributes,
			String[] uniqueAttributes, String[] hasOne, String[] hasOneForeignColumn, String[] hasMany, String[] hasManyForeignColumn,
			String[] hasManyMany,String[] hasManyManyInvolvedModel, String[] hasManyManyInvolvedModelForeignColumn, boolean caseSensitive) {
		this.namespace = namespace;
		this.modelName = modelName;
		this.attributes = attributes;
		this.generatedAttribute = generatedAttribute;
		this.dataTypes = dataTypes;
		this.primaryAttributes = primaryAttributes;
		this.uniqueAttributes = uniqueAttributes;
		this.hasOne = hasOne;
		this.hasOneForeignColumn = hasOneForeignColumn;
		this.hasMany = hasMany;
		this.hasManyForeignColumn = hasManyForeignColumn;
		this.hasManyMany = hasManyMany;
		this.hasManyManyInvolvedModel = hasManyManyInvolvedModel;
		this.hasManyManyInvolvedModelForeignColumn = hasManyManyInvolvedModelForeignColumn;
		this.caseSensitive = caseSensitive;	
	}


	
	public ModelDef() {

	}



	@Override
	public String getNamespace() {
		return namespace;
	}

	@Override
	public String getModelName() {
		return modelName;
	}

	@Override
	public String[] getAttributes() {
		return attributes;
	}

	@Override
	public String getGeneratedAttribute(){
		return generatedAttribute;
	}
	
	@Override
	public String[] getDataTypes() {
		return dataTypes;
	}

	@Override
	public Object[] getValues() {
		return values;
	}

	@Override
	public String[] getHasMany() {
		return hasMany;
	}

	@Override
	public String[] getHasManyForeignColumn() {
		return hasManyForeignColumn;
	}

	@Override
	public String[] getHasManyMany() {
		return hasManyMany;
	}

	
	
	@Override
	public String[] getHasManyManyInvolvedModel() {
		return hasManyManyInvolvedModel;
	}

	@Override
	public String[] getHasManyManyInvolvedModelForeignColumn() {
		return hasManyManyInvolvedModelForeignColumn;
	}

	@Override
	public String[] getPrimaryAttributes() {
		return primaryAttributes;
	}

	@Override
	public String[] getUniqueAttributes() {
		return uniqueAttributes;
	}

	@Override
	public String[] getHasOne() {
		return hasOne;
	}

	@Override
	public String[] getHasOneForeignColumn() {
		return hasOneForeignColumn;
	}

	@Override
	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	@Override
	public void setModelName(String table) {
		this.modelName = table;
	}

	@Override
	public void setAttributes(String[] columns) {
		this.attributes = columns;
	}

	@Override
	public void setDataTypes(String[] dataTypes) {
		this.dataTypes = dataTypes;
	}

	@Override
	public void setValues(Object[] values) {
		this.values = values;
	}

	@Override
	public void setPrimaryAttributes(String[] primaryColumns) {
		this.primaryAttributes = primaryColumns;
	}

	@Override
	public void setUniqueAttributes(String[] uniqueColumns) {
		this.uniqueAttributes = uniqueColumns;
	}

	@Override
	public void setHasMany(String[] hasMany) {
		this.hasMany = hasMany;
	}

	@Override
	public void setHasManyForeignColumn(String[] hasManyForeignColumn) {
		this.hasManyForeignColumn = hasManyForeignColumn;
	}

	@Override
	public void setHasManyMany(String[] hasManyMany) {
		this.hasManyMany = hasManyMany;
	}

	@Override
	public void setHasManyManyInvolvedModel(String[] hasManyManyInvolvedModel) {
		this.hasManyManyInvolvedModel = hasManyManyInvolvedModel;
	}

	@Override
	public void setHasManyManyForeignColumn(String[] hasManyManyForeignColumn) {
		this.hasManyManyInvolvedModelForeignColumn = hasManyManyForeignColumn;
	}

	@Override
	public void setHasOne(String[] hasOne) {
		this.hasOne = hasOne;
	}
	
	@Override
	public void setHasOneForeignColumn(String[] hasOneForeignColumn) {
		this.hasOneForeignColumn = hasOneForeignColumn;
	}

	@Override
	public String getPrimaryColumn(){
		if(this.primaryAttributes != null){
			return this.primaryAttributes[0];
		}
		return null;
	}
	
	@Override
	public String[] getPrimaryColumns() {
		return getPrimaryAttributes();
	}

	@Override
	public String getForeignKeyColumn(String modelName){
		//System.out.println("Searching of foreign key of "+modelName+" from table "+this.modelName);
		for(int i = 0; i < this.hasOne.length; i++){
			if(modelName.equalsIgnoreCase(this.hasOne[i])){
				return this.hasOneForeignColumn[i];
			}
		}
		return null;
	}
	
	@Override
	public String[] getForeignKeyColumns(String modelName) {
		List<String> foreignColumnList = new ArrayList<String>();
		for(int i = 0; i < this.hasOne.length; i++){
			if(modelName.equalsIgnoreCase(this.hasOne[i])){
				foreignColumnList.add(hasOneForeignColumn[i]);
			}
		}
		if(foreignColumnList.size() == 0){
			return null;
		}
		return foreignColumnList.toArray(new String[foreignColumnList.size()]);
	}

	@Override
	public void setGeneratedAttribute(String generatedAttribute) {
		this.generatedAttribute = generatedAttribute;
	}

	@Override
	public boolean isCaseSensitive() {
		return caseSensitive;
	}

	@Override
	public void setCaseSensitive(boolean caseSensitive) {
		this.caseSensitive = caseSensitive;
	}
	
	@Override
	public String toSummaryString(){
		StringBuffer sb = new StringBuffer();
		sb.append("model "+modelName+"{");
		sb.append("\n\tnamespace:"+namespace);
		sb.append("\n\tAttributes: ["+Arrays.asList(attributes)+"]");
		sb.append("\n\tdataTypes:"+(dataTypes!= null ? Arrays.asList(dataTypes):null));
		sb.append("\n\tgenerated:"+generatedAttribute);
		sb.append("\n\tprimary:"+(primaryAttributes != null? Arrays.asList(primaryAttributes): null));
		sb.append("\n\tuniques:"+(uniqueAttributes!= null ? Arrays.asList(uniqueAttributes): null));
		sb.append("\n\thasOne:"+Arrays.asList(hasOne));
		sb.append("\n\thasOneForeignColumn:"+(hasOneForeignColumn!=null? Arrays.asList(hasOneForeignColumn):null));
		sb.append("\n\thasMany:"+(hasMany!=null?Arrays.asList(hasMany):null));
		sb.append("\n\thasManyForeignColumn:"+(hasManyForeignColumn!=null?Arrays.asList(hasManyForeignColumn):null));
		sb.append("\n\tcaseSensitive:"+caseSensitive);
		sb.append("\n}");
		return sb.toString();
	}
}
